package com.echat.serviceapigateway.security.service.impl;

import com.echat.commonlib.constant.ErrorCode;
import com.echat.commonlib.constant.ErrorCodeMsg;
import com.echat.commonlib.exception.exc.EchatSecurityException;
import com.echat.commonlib.util.SpringContextUtil;
import com.echat.serviceapigateway.security.config.CacheConfig;
import com.echat.serviceapigateway.security.constant.Constants;
import com.echat.serviceapigateway.security.mapper.TokenGetLimitMapper;
import com.echat.serviceapigateway.security.model.authorization.TokenGetLimit;
import com.echat.serviceapigateway.security.service.TokenGetLimiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

/**
 * Created by chenmohan on 2018/09/12
 *
 * @description
 */
@Service
public class TokenGetLimitService implements TokenGetLimiService {

    @Autowired
    TokenGetLimitMapper tokenGetLimitMapper;

    @Override
    public List<TokenGetLimit> listTokenGetLimit() {
        List<TokenGetLimit> tokenGetLimitList = tokenGetLimitMapper.selectAll();
        return tokenGetLimitList;
    }

    /**
     * 通过userId获取该用户今日token请求次数上限
     * @param userId
     * @return
     */
    @Cacheable(value = CacheConfig.CACHE_TOKEN_GET_LIMIT, key = "#userId")
    @Override
    public Integer getTokenGetLimitByUserId(Long userId) {
        Example example = new Example(TokenGetLimit.class);
        example.createCriteria().andEqualTo("userId", userId);
        TokenGetLimit tokenGetLimit = tokenGetLimitMapper.selectOneByExample(example);
        if (tokenGetLimit == null) {
            throw new EchatSecurityException(ErrorCode.INVAILD_ACCESS_KEY, ErrorCodeMsg.INVAILD_ACCESS_KEY);
        }
        /*TODO:以后再修改，设置过期时间，过期时间为到次日零点的秒数
        Duration between = Duration.between(tokenGetLimit.getRefreshTime(), LocalDateTime.now());
        if(between.toHours()>=24){

        }
        */
        return tokenGetLimit.getGetTimes();
    }

    @CachePut(value = CacheConfig.CACHE_TOKEN_GET_LIMIT, key = "#userId")
    @Override
    public void initTokenGetLimit(Long userId) {
        tokenGetLimitMapper.insertSelective(
                TokenGetLimit.builder()
                        .userId(userId)
                        .getTimes(Constants.TOKEN_GET_LIMIT).build()
        );
    }

    @CachePut(value = CacheConfig.CACHE_TOKEN_GET_LIMIT, key = "#update.userId")
    @Override
    public Integer modifyTokenGetLimit(TokenGetLimit update) {
        tokenGetLimitMapper.updateByPrimaryKeySelective(update);
        return update.getGetTimes();
    }

    @Override
    public void refreshTokenGetLimit() {
        //以后可能会有针对每个用户不同的token获取次数限制
        List<TokenGetLimit> tokenGetLimits = tokenGetLimitMapper.selectAll();
        for(TokenGetLimit limit : tokenGetLimits){
            limit.setGetTimes(Constants.TOKEN_GET_LIMIT);
            ((TokenGetLimiService)SpringContextUtil.getBean(this.getClass())).modifyTokenGetLimit(limit);
        }
    }

}
